home *** CD-ROM | disk | FTP | other *** search
/ Space & Astronomy / Space and Astronomy (October 1993).iso / mac / programs / satrack / SS4EXE.ZIP / SEESAT4.ZIP / DRIVER.C < prev    next >
Text File  |  1992-01-05  |  15KB  |  644 lines

  1. /*
  2. DRIVER.C
  3. by Paul S. Hirose, 1992 Jan 4
  4. main module for the SEESAT satellite tracking program.
  5.  
  6. This file is in the public domain.
  7.  
  8. 0 - 99
  9.  
  10. */
  11.  
  12. #include "B:SEESAT.H"    /* global header */
  13.  
  14. /* At startup, SEESAT will execute the commands in AUTOEX */
  15. #define AUTOEX "SEESAT.BAT"
  16.  
  17. /* library functions and #defines used in this file:
  18.     atof() exit() fclose() FILE
  19.     fopen() getchar() isspace() NULL printf() strcmp()
  20. */
  21.  
  22. #if ECOC
  23. extern void exit(), printf();
  24. extern FILE *fopen();
  25. extern double atof();
  26. #endif
  27.  
  28.  
  29. /* The HLTRUN macro is placed in the command interpreter loop in main(), and
  30. in the prediction loop in run().  HLTRUN allows you to easily install an
  31. abort feature for your system.  I recommend doing the abort itself with
  32. LONGJMP(reset, 1).  This will return you to the command line and turn off the
  33. batch flag, from anywhere in the program.  The aborts I've provided for Laser
  34. C and Turbo C are activated by pressing any key. */
  35.  
  36. #if ECOC
  37. #define HLTRUN
  38. #endif
  39.  
  40. #if LASERC
  41. #include <osbind.h>
  42. #define HLTRUN\
  43.     if (Bconstat(2)) {\
  44.         Bconin(2);\
  45.         LONGJMP(reset, 1);\
  46.     }
  47. #endif
  48.  
  49. #if TURBOC
  50. #include <conio.h>
  51. #define HLTRUN\
  52.     if (bioskey(1)) {\
  53.         bioskey(0);\
  54.         LONGJMP(reset, 1);\
  55.     }
  56. #endif
  57.  
  58.  
  59. /*##################### STATIC FUNCTIONS #####################*/
  60.  
  61. static void
  62.     bye(), center(), exbat(),
  63.     help(), ifprn(),
  64.     offset(), prnval(), rep(), ret(),
  65.     run(), sethor(), setmag(), setmb(), setmer(),
  66.     settz(), skip(), span(),
  67.     start(), step(), stop(), xrun();
  68.  
  69. static char *s_in();
  70.  
  71.  
  72. /*############################## DATA ##############################*/
  73.  
  74. static double
  75.     tf,    /* end of prediction run */
  76.     delt,    /* time interval between predictions */
  77.     tspan;    /* length of run */
  78.  
  79. static float magbias;    /* to be applied to apparent magnitude */
  80.  
  81. struct jdtim t1;    /* CENTER & START values share this */
  82.  
  83. struct comd {
  84.     char *name;        /* name of command */
  85.     void (*funp)();        /* ptr to function that executes it */
  86. };
  87.  
  88. static struct comd comds[] = {
  89.     {"STEP", step},
  90.     {"START", start},
  91.     {"STOP", stop},
  92.     {"SPAN", span},
  93.     {"CENTER", center},
  94.     {"CENTRE", center},
  95.     {"RUN", run},
  96.  
  97.     {"LOAD", load},        /* READEL.C */
  98.     {"OPEN", opn},        /* READEL.C */
  99.     {"INDEX", indx},    /* READEL.C */
  100.     {"NEXT", next},        /* READEL.C */
  101.  
  102.     {"SUN", dusk},        /* ASTRO.C */
  103.     {"MOON", moon},        /* ASTRO.C */
  104.     {"PARA", parall},    /* ASTRO.C */
  105.  
  106.     {"PRINT?", ifprn},
  107.     {"REPEAT", rep},
  108.     {"SKIP", skip},
  109.     {"EX", exbat},
  110.     {"RET", ret},
  111.  
  112.     {"AOP", aop},        /* READEL.C */
  113.     {"B", b},        /* READEL.C */
  114.     {"E", ein},        /* READEL.C */
  115.     {"EPOCH", epoc},    /* READEL.C */
  116.     {"I", inc},        /* READEL.C */
  117.     {"MA", ma},        /* READEL.C */
  118.     {"MM", mm},        /* READEL.C */
  119.     {"MMDOT", setnd},    /* READEL.C */
  120.     {"MMDOTDOT", setndd},    /* READEL.C */
  121.     {"NAME", setnam},    /* READEL.C */
  122.     {"RAAN", raan},        /* READEL.C */
  123.     {"ACTUAL", setact},    /* READEL.C */
  124.     {"NOMINAL", setnom},    /* READEL.C */
  125.     {"MAG", setmag},
  126.     {"MAGBIAS", setmb},
  127.     {"OFFSET", offset},
  128.  
  129.     {"LAT", setlat},    /* ASTRO.C */
  130.     {"LON", setlon},    /* ASTRO.C */
  131.     {"HEIGHT", seth},    /* ASTRO.C */
  132.     {"ZONE", settz},
  133. #if ENPRE
  134.     {"PRECESS", setep},    /* ASTRO.C */
  135. #endif
  136.     {"LENGTH", setlen},    /* READEL.C */
  137.     {"MERIDIAN", setmer},
  138.     {"ALL", sethor},
  139. #if ECOC == 0
  140.     {"HELP", help},
  141. #endif
  142.     {"EXIT", bye},
  143.     {NULL}
  144. };
  145.  
  146. static char *nullp = NULL;    /* constant */
  147. static char **ptok0;        /* points to start of cmd line */
  148.  
  149. static FILE *batfp;        /* batch file */
  150.  
  151. /* flags; set/reset by the CENTER, SPAN, START, STOP commands */
  152. static char fcenter, fspan, fstart, fstop;
  153.  
  154. /* this flag used by autom(), set by run() when a prediction is printed */
  155. static char fvis;
  156.  
  157. static char fbatch;    /* batch mode flag */
  158.  
  159. /*############################## CODE ##############################*/
  160.  
  161. main()
  162. {
  163.     struct comd *comdp;
  164.     char *cp1, *cp2;
  165.  
  166.     ETEST((0, 1, 3, &pi));    /* dummy call to get control of brkpt */
  167.  
  168. #if ECOC
  169.     printf("SEESAT (SGP) %s by Paul Hirose\n", vers);
  170. #else
  171.     printf("SEESAT (SGP4) %s by Paul Hirose\n", vers);
  172. #endif
  173.  
  174.     /* Ecosoft C doesn't allow negative initializers! */
  175.     xj3 = -.253881e-5;
  176.     xj4 = -1.65597e-6;
  177.  
  178.     /* Attempt to open the auto-execute batch file.  Setting fbatch will
  179.     redirect command input to the file. */
  180.  
  181.     if (batfp = fopen(AUTOEX, "r"))
  182.         fbatch = '\001';    /* set batch flag */
  183.  
  184.     /* Execution is vectored back here for all errors */
  185.     if (SETJMP(reset))
  186.     /* returned from a longjmp(); turn off batch file flag */
  187.         fbatch = '\000';
  188.  
  189.     tokp = &nullp;    /* clear command line */
  190.  
  191.     for (;;) {    /* main loop */
  192.         HLTRUN                /* optional abort macro */
  193.         while (*tokp == NULL) {        /* cmd line exhausted */
  194.             tok();
  195.             ptok0 = tokp;
  196.         }
  197.         cp1 = *tokp;        /* point to first command */
  198.  
  199.         /* Find the command in the comds[] table, execute the
  200.         corresponding function */
  201.  
  202.         for (comdp = comds; (cp2 = comdp->name) && strcmp(cp1, cp2);
  203.           ++comdp)
  204.             ;
  205.         if (cp2) {    /* found command; execute */
  206.             ++tokp;        /* point to first arg */
  207.             (*comdp->funp)();
  208.             ++tokp;        /* point to next command */
  209.         } else {
  210.             printf("%s: BAD COMMAND\n", cp1);
  211.             LONGJMP(reset, 1);
  212. }    }    }
  213.  
  214.  
  215. static void
  216. bye()
  217. {
  218.     hfree();    /* release index space */
  219.     exit(0);
  220. }
  221.  
  222.  
  223. static void
  224. center()
  225. {
  226.     tokjum(&t1);        /* load t1 with CENTER value */
  227.     fcenter = '\001';
  228.     fstop = fstart = '\000';    /* start & stop flags */
  229.     xrun();
  230. }
  231.  
  232.  
  233. static void
  234. exbat()
  235. /* Execute as a batch file the next token on the command line */
  236. {
  237.     if (batfp)    /* a batch file is already open */
  238.         fclose(batfp);
  239.  
  240.     if ((batfp = fopen(*tokp, "r")) == NULL) {
  241.         printf("CAN'T OPEN %s\n", *tokp);
  242.         LONGJMP(reset, 1);
  243.     }
  244.     fbatch = '\001';
  245. }
  246.  
  247.  
  248. #if ECOC == 0
  249.  
  250. static void
  251. help()
  252. {
  253.     printf("HELP EXIT RUN INDEX NEXT MERIDIAN ALL PRINT? REPEAT \
  254. SKIP RET : no argument\n\n");
  255.  
  256.     printf("STEP SPAN OFFSET ZONE : <time>\n");
  257.     printf("   <time> = hhmm:ss.sss...\n");
  258.     printf("   seconds optional, leading zeros optional, \
  259. negative sign allowed\n");
  260.     printf("   ZONE = local - UTC\n\n");
  261.  
  262.     printf("START STOP CENTER CENTRE PARA PRECESS MOON SUN \
  263. ACTUAL NOMINAL : <date time>\n");
  264.     printf("   <date time> = yyyy mmm dd hhmm:ss.sss...        \
  265. example:  1992 Jan 4 1830\n\n");
  266.  
  267.     printf("OPEN EX : <filename>\n");
  268.     printf("NAME LOAD : <satellite name>\n");
  269.     printf("LENGTH <1 - 22>\n");
  270.     printf("EPOCH <NORAD epoch>\n");
  271.     printf("   example:  EPOCH 91032.78295309\n\n");
  272.  
  273.     printf("AOP B E I MA MM MMDOT MMDOTDOT RAAN MAG MAGBIAS \
  274. LAT LON HEIGHT : <number>\n");
  275.     printf("   integer, fixed point, or exponential format allowed\n");
  276.     printf("   south lat & west lon are negative, height = kilometers\n");
  277.  
  278.     --tokp;        /* token pointer */
  279. }
  280.  
  281. #endif
  282.  
  283.  
  284. static void
  285. ifprn()
  286. /* Causes next command to be executed if the print flag is true.  Else,
  287. skip next command. */
  288. {
  289.     if (fvis)
  290.         --tokp;
  291. }
  292.  
  293.  
  294. static void
  295. offset()
  296. /* Apply a time offset to epoch of elements.  Do not set iflag since
  297. initialization is independent of time. */
  298. {
  299.     toffs = atomin(*tokp);
  300. }
  301.  
  302.  
  303. static void
  304. prnval(time)
  305. double time;    /* local time */
  306. /* All tabular data from a prediction run is printed here.  Except for local
  307. time of day, all data comes from global variables in SEESAT.H. */
  308. {
  309.     char **cpp;
  310.  
  311.     /* time, azimuth, elevation. */
  312.     printf("%s %3d%3d  ", timstr(time),
  313.       (int) (azel.x * ra2de + .5),
  314.       (int) (azel.y * ra2de + .5));
  315.  
  316.     /* Right Ascension, declination. */
  317.     cpp = degdms(2, radec.x / twopi * 24.);
  318.     printf("%2sh%2sm ", cpp[0], cpp[1]);
  319.     cpp = degdms(1, radec.y * ra2de);
  320.     printf("%3s %2s'  ", cpp[0], cpp[1]);
  321.  
  322.     /* slant range, sun elevation at satellite */
  323.     printf("%5ld %3d ", (long int) (radec.z * xkmper), elsusa);
  324.  
  325.     /* apparent magnitude.  Flag relative mag with '*'. */
  326.     printf("%c%4.1f  ", mflag ? ' ' : '*', apmag + magbias);
  327.  
  328.     /* altitude */
  329.     printf("%5ld ", (long int) (latlon.z * xkmper));
  330.  
  331.     /* latitude */
  332.     printf("%4.1f%c ", FABS(latlon.y) * ra2de,
  333.       (latlon.y >= 0.) ? 'N' : 'S');
  334.  
  335.     /* longitude */
  336.     printf("%5.1f%c\n", FABS(latlon.x) * ra2de,
  337.       (latlon.x >= 0.) ? 'E' : 'W');
  338. }
  339.  
  340.  
  341. static void
  342. rep()
  343. /* causes re-execution of the command line */
  344. {
  345.     tokp = ptok0 - 1;
  346. }
  347.  
  348.  
  349. static void
  350. ret()
  351. /* toggle the batch mode flag, disregard rest of command line, get next
  352. command line */
  353. {
  354.     if (fbatch)
  355.         fbatch = '\000';
  356.     else
  357.     /* set fbatch only if a batch file is open */
  358.         fbatch = batfp != NULL;
  359.  
  360.     tok();
  361.     --tokp;
  362. }
  363.  
  364.  
  365. static void
  366. run()
  367. /* Execute prediction run */
  368. {
  369.     double tsince, mins, temp;
  370.     long int jd;
  371.     unsigned int count;    /* no. of predictions */
  372.     static char mode;
  373.  
  374.     fvis = '\000';        /* clear "visible flag" */
  375.  
  376.     if (xno == 0.) {
  377.         printf("NO ELEMENTS\n");
  378.         LONGJMP(reset, 1);
  379.     }
  380.  
  381.     /* jd & mins are local time */
  382.     jd = t1.jd;
  383.     mins = t1.time;
  384.  
  385.     /* set mode */
  386.     if (fstart && fstop)
  387.         mode = 1;
  388.     else if (fspan)
  389.         if (fstart)
  390.             mode = 3;
  391.         else if (fcenter)
  392.             mode = 2;
  393.  
  394.     fstart = fstop = fspan = fcenter = '\000';
  395.  
  396.     /* tsince = CENTER or START time (whichever was given last) */
  397.     tsince = t1.jd * xmnpda - 720. + t1.time - tzone;
  398.  
  399.     /* establish the parameters of the run, according to current mode */
  400.     switch (mode) {
  401.     case 1:        /* start stop */
  402.         temp = tf - tsince;        /* length of run */
  403.         if (temp < 0.) {
  404.             printf("STOP < START\n");
  405.             LONGJMP(reset, 1);
  406.         }
  407.         break;
  408.     case 2:
  409.         temp = .5 * tspan;
  410.         mins -= temp;
  411.         while (mins < 0.) {    /* start on previous day */
  412.             mins += xmnpda;
  413.             --jd;
  414.         } tsince -= temp;    /* was initially CENTER value */
  415.         /* fall thru to next case */
  416.     case 3:        /* start span */
  417.         temp = tspan;
  418.         break;
  419.     default:
  420.         printf("NOT ENOUGH RUN PARAMETERS\n");
  421.         LONGJMP(reset, 1);
  422.     }
  423.  
  424.     if (delt == 0.) {        /* zero span */
  425.         printf("STEP = 0\n");
  426.         LONGJMP(reset, 1);
  427.     }
  428.     count = temp / delt + 1.95;    /* no. of predictions */
  429.  
  430.     tsince -= epoch;
  431.     printf("%s   ", name);    /* satellite name */
  432.     printf("%s", jdstr(jd));    /* start date */
  433.     if (toffs)
  434.         printf("   offset = %s", timstr(toffs));
  435.     printf("\n");
  436.     printf("  time   az el   R.A.    dec    range sun   mag    alt  la\
  437. t    lon\n");
  438.  
  439.     do {
  440.         HLTRUN        /* optional run abort function */
  441.         if (mins >= xmnpda) {        /* crossed midnight */
  442.             mins -= xmnpda;
  443.             printf("%s\n", jdstr(++jd));    /* print new date */
  444.         }
  445.         FTEST((1, 1, 2, &tsince));
  446.         MODEL(tsince - toffs);    /* call prediction model */
  447.         DTEST((2, 1, &elsusa));
  448.         if (xyztop(tsince + epoch)) {
  449.         /* above horizon; print line of data */
  450.             FTEST((3, 1, 2, &mins));
  451.             prnval(mins);
  452.             fvis = '\001';    /* set visible flag */
  453.         } mins += delt;
  454.         tsince += delt;
  455.     } while (--count);
  456.     --tokp;        /* because this cmd takes no args */
  457. }
  458.  
  459.  
  460. static char *
  461. s_in(prompt, buffer)
  462. char *prompt, *buffer;
  463. /* Prints prompt[] on console, puts typed string in buffer[].  Backspacing
  464. will correct typing mistakes.  Will not allow backspacing past the start of
  465. buffer.  Returns pointer to buffer. */
  466. {
  467.     static char c, *ptr, last;
  468.  
  469.     for (ptr = prompt; *ptr; ++ptr)
  470.         ;    /* point to terminating null of prompt */
  471.     last = *(ptr - 1);        /* fetch char before the null */
  472.  
  473.     printf("%s", prompt);
  474.     ptr = buffer;
  475.     while ((c = getchar()) != '\n')
  476.         if (c == '\b')
  477.             if (ptr == buffer)
  478.                 printf("%c", last);
  479.             else
  480.                 --ptr;
  481.         else
  482.             *ptr++ = c;
  483.  
  484.     *ptr = '\0';
  485.     return buffer;
  486. }
  487.  
  488.  
  489. static void
  490. sethor()
  491. /* toggles the flag that suppress printout of predictions below horizon */
  492. {
  493.     aflag = !aflag;
  494.     --tokp;        /* because this cmd takes no args */
  495. }
  496.  
  497.  
  498. static void
  499. setmag()
  500. /* set absolute magnitude */
  501. {
  502.     abmag = atof(*tokp);
  503.     mflag = '\001';        /* set magnitude flag */
  504. }
  505.  
  506.  
  507. static void
  508. setmb()
  509. /* set magnitude bias */
  510. {
  511.     magbias = atof(*tokp);
  512. }
  513.  
  514.  
  515. static void
  516. setmer()
  517. /* toggles flag that selects Greenwich or local meridian for longitude
  518. readout. */
  519. {
  520.     printf("%s meridian\n", (gflag = !gflag) ? "Greenwich" : "local");
  521.     --tokp;        /* because this cmd takes no args */
  522. }
  523.  
  524.  
  525. static void
  526. settz()
  527. /* sets time zone (local time - UTC) */
  528. {
  529.     tzone = atomin(*tokp);
  530. }
  531.  
  532.  
  533. static void
  534. skip()
  535. /* causes next command to be skipped */
  536. {
  537. }
  538.  
  539.  
  540. static void
  541. span()
  542. {
  543.     tspan = atomin(*tokp);
  544.     fspan = '\001';        /* set flag */
  545.     xrun();
  546. }
  547.  
  548.  
  549. static void
  550. start()
  551. {
  552.     tokjum(&t1);        /* load struct with START time */
  553.     fstart = '\001';    /* set flag */
  554.     fcenter = '\000';    /* center flag */
  555.     xrun();
  556. }
  557.  
  558.  
  559. static void
  560. step()
  561. {
  562.     delt = atomin(*tokp);
  563.     xrun();
  564. }
  565.  
  566.  
  567. static void
  568. stop()
  569. {
  570.     tf = tokmin();
  571.     fstop = '\001';        /* set flag */
  572.     fcenter = '\000';    /* center flag */
  573.     xrun();
  574. }
  575.  
  576.  
  577. void
  578. tok()
  579. /* Inputs a command line from console (or batch file, if fbatch true). 
  580. String is converted to upper case.  Each ' ' in the string is replaced with
  581. '\0' & successive members of tokens[] point to the sub-strings ("tokens")
  582. thus created.  A character sequence containing spaces is considered a single
  583. token if it's enclosed in quotes (the quotes will not become part of the
  584. token).  End of tokens[] is marked by NULL.  On exit, tokp points to
  585. tokens[0], i.e., it works like the traditional C variable argv. */
  586. {
  587.     char *cptr;
  588.     char c;
  589.     int notok;            /* flag; 1 = not in a token */
  590.     static char
  591.         *tokens[15],        /* pointers to cmd line tokens */
  592.         buffer[85];        /* command line buffer */
  593.  
  594.     if (fbatch)
  595.         if (getlin(buffer, 85, batfp) == 0) {
  596.             printf("end of batch file\n");
  597.             fclose(batfp);
  598.             batfp = NULL;    /* to indicate no batch file open */
  599.             LONGJMP(reset, 1);
  600.         } else        /* show the batch file line */
  601.             printf(">%s\n", buffer);
  602.  
  603.     else {
  604.     /* display '>', get command line from keyboard */
  605.         s_in(">", buffer);
  606.     }
  607.     stoup(buffer);
  608.     tokp = tokens;        /* point to 1st element of tokens[] */
  609.     notok = 1;        /* set "not in token" flag true */
  610.     for (cptr = buffer; c = *cptr; ++cptr)
  611.         if (isspace(c)) {
  612.             notok = 1;
  613.             *cptr = '\0';    /*  replace ' ' with '\0' */
  614.         } else if (notok) {    /* first char of a token */
  615.             notok = 0;
  616.             if (c != '"')
  617.                 *tokp++ = cptr;
  618.             else {        /* quoted token */
  619.                 *tokp++ = ++cptr;
  620.                 while ((c = *++cptr) && c != '"')
  621.                 /* find closing '"' or end of string */
  622.                     ;
  623.                 if (c)        /* found '"' */
  624.                     *cptr = '\0';
  625.                 else        /* found '\0' */
  626.                     --cptr;
  627.         }    }
  628.     *tokp = NULL;        /* terminate tokens[] */
  629.     tokp = tokens;
  630. }
  631.  
  632.  
  633. static void
  634. xrun()
  635. /* do a run if command line is exhausted */
  636. {
  637.     if (tokp[1] == NULL) {
  638.         run();
  639.         ++tokp;        /* run() decremented it */
  640. }    }
  641. dicate no batch file open */
  642.             LONGJMP(reset, 1);
  643.         } else        /* show the batch file line */
  644.             printf(">%s\n", buffer);